﻿using System;

namespace PropertyChanges
{
    class Person : IPropertyChange
    {
        public string firstName;
        public string lastName;
        public Genders gender;
        public DateTime dateOfBirth;

        private PropertyChangedEventHandler propertyEventHandler;

        public event PropertyChangedEventHandler PropertyEventHandler
        {
            add
            {
                propertyEventHandler += value;
                Console.WriteLine("add");
            }
            remove
            {
                propertyEventHandler -= value;
                Console.WriteLine("remove");
            }
        }
        public string FirstName
        {
            get { return FirstName; }
            set
            {
                if (value == null)
                {
                    throw new NullReferenceException("The value of First Name is null!");
                }

                string oldValue = this.firstName;
                this.firstName = value;
                this.OnPropertyChanged("firstName", oldValue, value);
            }
        }
        public string LastName
        {
            get { return LastName; }
            set
            {
                if (value == null)
                {
                    throw new NullReferenceException("The value of Last Name is null!");
                }

                string oldValue = this.lastName;
                this.lastName = value;
                this.OnPropertyChanged("lastName", oldValue, value);
            }
        }
        public Genders Gender
        {
            get { return Gender; }
            set
            {
                Genders oldValue = this.gender;
                this.gender = value;
                this.OnPropertyChanged("gender", oldValue, value);
            }
        }
        public DateTime DateOfBirth
        {
            get { return DateOfBirth; }
            set
            {
                if (value == null)
                {
                    throw new NullReferenceException("The value of DateOfBirth is null!");
                }

                DateTime oldValue = this.dateOfBirth;
                this.dateOfBirth = value;
                this.OnPropertyChanged("dateOfBirth", oldValue, value);
            }
        }

        protected void OnPropertyChanged(string propertyName, object oldValue, object newValue)
        {
            if (propertyEventHandler != null)
            {
                propertyEventHandler(this, new PropertyChangedEventArgs(propertyName, oldValue, newValue));
            }

        }

        public Person()
        {
            this.FirstName = "";
            this.LastName = "";
            this.Gender = Genders.Male;
            this.DateOfBirth = DateTime.Now;

            this.InitializeEventHandlers();
        }

        private void InitializeEventHandlers()
        {
            propertyEventHandler += new PropertyChangedEventHandler(Person_PropertyEventHandler);
        }

        void Person_PropertyEventHandler(object sender, PropertyChangedEventArgs args)
        {
            Console.WriteLine("Field \"{0}\" was changed from {1} to {2}", args.PropertyName, args.OldValue, args.NewValue);
        }
    }
}
